Examples of Kernel design

There are many examples of the first class of kernel available for study, such as Linux, NetBSD, FreeBSD and OpenBSD. We are not particularly concerned with these in this project.

There are several microkernel designs which lend themselves well to the second category (single-server) approach. Mach with the Lites single-server is probably the most popular example of this type. There is also an ongoing project at GMD[*] to port Linux to the L4 microkernel.

The Chorus [#!coulouris!#] operating system was designed for a multi-server approach. In Chorus terminology, the tasks are called actors. In an attempt to improve performance, actors may be co-located with the microkernel and run with kernel privilege. This is because switching from kernel mode to user mode is extremely expensive with some processors, notably the Intel x86 family. One study [#!lied95!#] claims that switching to kernel mode and back to user mode takes 107 cycles with the Intel 486.

Nevertheless, the Chorus microkernel and the Mach microkernel share many similar concepts. Both use the concept of ports to implement interprocess communication (IPC), but they implement protection in a different manner. In Chorus, a 64 bit key is used in addition to a port ID to make it difficult for a malicious actor to send a message to an unsuspecting actor. In Mach, port send rights are administered by the microkernel which allows tasks to revoke send rights from tasks they no longer trust, and additionally to implement send-once rights, where a client may allow a task to send it a reply, but send no more messages. L4 takes a radically different approach by not attempting to implement protection within the microkernel, but to adopt a distributed protection scheme.

All three microkernels have very different ideas about implementing device drivers. Mach retains the device drivers within the microkernel. Chorus removes them into actors, which are co-located with the microkernel, but they can still be developed externally to the microkernel since it presents the same API to the actor. In L4, device drivers are not part of the microkernel at all. They are implemented as processes which claim any interrupts they require and request portions of the memory map which correspond to memory mapped I/O regions. Interrupts are implemented by the microkernel sending a message to the driver which has claimed that interrupt. This is similar to Chorus, but L4 does not require colocation in order to achieve acceptable performance. This is probably due to the extremely efficient IPC in L4.

Writing new device drivers is one of the most common requirements when developing, maintaining and porting kernels, so a system which permits drivers to be developed, tested and debugged more efficiently and safely is extremely useful.

Mach and Chorus were developed in a very different way to L4. Their designers implemented features that they thought would enable people to implement other operating systems on top of the microkernel in an effective manner. Instead, L4 implements what its designers consider to be a minimal set of features that are sufficient to implement an operating system. The designers are then able to expend much more effort on optimising the few remaining operations which are used frequently.

For example, when IPC was designed in L4, the designers calculated the minimum time possible for a message to be delivered, assuming an optimum scenario. They then set themselves a target of double this. A full description of this method can be found in [#!ipcdesign!#].